package com.huan.study.mybatis.handler;

import com.huan.study.mybatis.annotation.DecryptField;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author YanXxx
 * @date 2022-11-03 18:03
 */
public interface DecryptHandler {

    /**
     * 解密方式抽取
     *
     * @param decryptValue 解密值
     * @return 解密值
     */
    String decryptMethod(String decryptValue);

    /**
     * 解密
     *
     * @param result resultType的实例
     * @param <T>    T
     * @return 解密后结果集
     * @throws IllegalAccessException 字段不可访问异常
     */
    default <T> T decrypt(T result) throws IllegalAccessException {
        //取出resultType的类
        Class<?> resultClass = result.getClass();
        Set<Field> decryptField = getDecryptField(resultClass.getDeclaredFields());
        for (Field field : decryptField) {
            //result相当于字段的访问器
            Object object = field.get(result);
            //String的解密
            if (object instanceof String) {
                String decryptValue = (String) object;
                //对注解的字段进行逐一解密
                String decrypted = decryptMethod(decryptValue);
                field.set(result, decrypted);
            }
        }
        return result;
    }

    /**
     * 取出 被Decrypt注解的字段
     *
     * @param declaredFields 声明的字段
     * @return 被Decrypt注解的字段Set集合
     */
    default Set<Field> getDecryptField(Field[] declaredFields) {
        Set<Field> fieldSet = Arrays.stream(declaredFields).filter(field ->
                        field.isAnnotationPresent(DecryptField.class))
                .collect(Collectors.toSet());
        for (Field field : fieldSet) {
            field.setAccessible(true);
        }
        return fieldSet;
    }
}
